#include "Command.h"


const int NUM_OF_SLOTS = 2;

//concrete object



class Light:public IObject
{
public:
	Light()
	{

	}
	/*Light(bool status):_status(status)
	{

	}*/
	~Light()
	{

	}

	void Display()
	{
		string str = (!_status)?("The light is off!"):("The light is on!");
		cout<<str<<endl;
	}
	//bool	_status;
};

class Fan:public IObject
{
public:
	Fan()
	{

	}
	/*Fan(bool status):_status(status)
	{

	}*/
	~Fan()
	{

	}

	void Display()
	{
		string str = (!_status)?("The Fan is off!"):("The Fan is on!");
		cout<<str<<endl;
	}

	//bool _status;
};

//specific command object

class LightOnCommand:public Command
{
public:
	LightOnCommand(Light* light):_light(light)
	{

	}
	~LightOnCommand() {}

	void Execute()
	{
		_light->On();
	}
	void Undo()
	{
		_light->Off();
	}

private:
	Light*	_light;
};

class LightOffCommand:public Command
{
public:
	LightOffCommand(Light* light):_light(light)
	{

	}
	~LightOffCommand() {}

	void Execute()
	{
		_light->Off();
	}

	void Undo()
	{
		_light->On();
	}

private:
	Light*	_light;
};

class FanOnCommand:public Command
{
public:
	FanOnCommand(Fan* fan):_fan(fan)
	{

	}
	~FanOnCommand() {}

	void Execute()
	{
		_fan->On();
	}
	void Undo() { _fan->Off(); }

private:
	Fan*		_fan;

};

class FanOffCommand:public Command
{
public:
	FanOffCommand(Fan* ifan):_fan(ifan)
	{

	}
	~FanOffCommand() {}

	void Execute()
	{
		_fan->Off();
	}
	void Undo() { _fan->On(); }

private:
	Fan*		_fan;

};

class NoCommand:public Command
{
public:
	NoCommand()
	{

	}
	~NoCommand(){}

	void Execute() {cout<<"No command obj"<<endl;}
	void Undo() { cout<<"No command obj"<<endl; }


};


//remote control class
class RemoteControl
{
public:
	RemoteControl()
	{
		_onslot = new Command*[NUM_OF_SLOTS];
		_offslot = new Command*[NUM_OF_SLOTS];
		
		NoCommand* pNoCmd = new NoCommand();
		for( int i = 0 ; i < NUM_OF_SLOTS; ++i)
		{
			_onslot[i] = pNoCmd;
			_offslot[i] = pNoCmd;
		}
		_undocommand = pNoCmd;
	}
	~RemoteControl()
	{
		//delete _undocommand;
		delete [](_offslot);
		delete [](_onslot);
	}
	
	void SetCommand(int i , Command* oncommand, Command* offcommand)
	{
		_onslot[i] = oncommand;
		_offslot[i] = offcommand;
	}

	void PressOffButton( int i )
	{
		_offslot[i]->Execute();
		_undocommand = _offslot[i];
	}

	void PressOnButton( int i )
	{
		_onslot[i]->Execute();
		_undocommand = _onslot[i];
	}

	void UndoButtonPressed()
	{
		_undocommand->Undo();
	}

private:
	Command**		_onslot;
	Command**		_offslot;
	Command*		_undocommand;
};


int main()
{
	RemoteControl* pCtrl = new RemoteControl();
	Light* pLight = new Light();
	LightOnCommand* pLCmd = new LightOnCommand(pLight);
	LightOffCommand* pLOfCmd = new LightOffCommand(pLight);

	Fan* pFan = new Fan();
	FanOnCommand* pOnFanCmd = new FanOnCommand(pFan);
	FanOffCommand* pOffFanCmd = new FanOffCommand(pFan);





	pCtrl->SetCommand( 0, pLCmd, pLOfCmd );
	pCtrl->PressOnButton( 0 );
	pCtrl->PressOffButton( 0 );
	pCtrl->UndoButtonPressed();
	pLight->Display();

	pCtrl->SetCommand( 1, pOnFanCmd, pOffFanCmd );
	pCtrl->PressOnButton( 1 );
	pCtrl->UndoButtonPressed();
	pFan->Display();
	
	delete pOffFanCmd;
	delete pOnFanCmd;
	delete pFan;
	delete pLOfCmd;
	delete pLCmd;
	delete pLight;
	delete pCtrl;

	cin.get();
	return 0;
}


